﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;

namespace Core.Interface
{
    //ModBusRTU也会继承此类
    public abstract class ModBusDevice
    {
        public abstract bool Connect();

        public abstract void Close();

        public bool ReadRegister(ushort startAddress, out ushort value)
        {
            bool result= ReadRegister(startAddress, 1, out ushort[] values);
            value = values[0];
            return result;
        }

        public abstract bool ReadRegister(ushort startAddress, ushort size, out ushort[] values);

        public bool WriteRegister(ushort startAddress, ushort value)
        {
            bool result = WriteRegister(startAddress, 1, new ushort[] { value});
            return result;
        }

        public abstract bool WriteRegister(ushort startAddress, ushort size, ushort[] values);

        public abstract bool ReadBit(ushort startAddress, ushort size, out bool[] values);

        public abstract bool WriteBit(ushort startAddress, ushort size, bool[] values);

        /// <summary>
        /// 断线重连
        /// </summary>
        /// <param name="n">重新连接的次数</param>
        /// <returns></returns>
        public void Reconnect()
        {
            try
            {
                Close();
                Thread.Sleep(10);
                Connect();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
        }

        public bool ReadFloat(ushort startAddress, ushort size, out float[] values)
        {
            try
            {
                bool result = false;
                values = new float[size];
                if (ReadRegister(startAddress, (ushort)(2 * size), out ushort[] tempValues))
                {

                    for (int i = 0; i < size; i++)
                    {
                        //一个浮点数是4个字节因此是i*4
                        values[i] = BitConverter.ToSingle(JoinU16(tempValues).ToArray(), 4 * i);
                    }
                    result = true;
                }
                return result;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
        }

        public bool WriteFloat(ushort startAddress, ushort size, float[] value)
        {
            try
            {
                List<byte> bytes = new List<byte>();
                for (int i = 0; i < size; i++)
                {
                    bytes.AddRange(BitConverter.GetBytes(value[i]));
                }
                ushort[] target = new ushort[bytes.Count / 2];
                for (int i = 0; i < target.Length; i++)
                {
                    target[i] = BitConverter.ToUInt16(bytes.ToArray(), i * 2);
                }
                return WriteRegister(startAddress, (ushort)(2 * size), target);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
        }

        /// <summary>
        /// 合并16位数值为字节集合
        /// </summary>
        /// <param name="uSArray"></param>
        /// <returns></returns>
        private List<byte> JoinU16(ushort[] uSArray)
        {
            List<byte> LB = new List<byte>();
            try
            {
                foreach (var item in uSArray)
                {
                    byte[] bArray = BitConverter.GetBytes(item);
                    LB.AddRange(bArray);
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
            return LB;
        }
    }
}
